package code.example.javassist.method;

import code.example.javassist.maker.ClassMarker;
import code.example.javassist.reflect.ClassReflector;
import code.example.javassist.reflect.ClassReflectorFactory;
import code.example.javassist.reflect.MethodsReflector;

import java.util.concurrent.atomic.AtomicLong;

public class MethodCallerMakerImpl implements MethodCallerMaker{
    AtomicLong atomicLong = new AtomicLong();
    @Override
    public MethodCaller make(Object obj, String method, Object[] parameter) throws Exception {
        String methodString = getCallerMethodString(obj,method,parameter);
        String newClassName =  MethodCaller.class.getName()+atomicLong.incrementAndGet();
        ClassMarker classMarker = new ClassMarker(newClassName);
        classMarker.addSuperClass(MethodCallerImpl.class);
        classMarker.addInterface(MethodCaller.class);
        classMarker.addMethod(methodString);
        Class<MethodCaller> classz = classMarker.make();
        return classz.newInstance();
    }
    public String getCallerMethodString(Object obj, String method, Object[] parameter) throws Exception {

        ClassReflector classReflector = ClassReflectorFactory.createClassReflector(obj.getClass());
        MethodsReflector methodsReflector = classReflector.createMethodsReflector();

        String className = obj.getClass().getName() ;
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("public Object call(Object obj ,String method, Object [] parameter) throws Exception {");
        stringBuilder.append("return ")
                    .append("((")
                     .append(className)
                    .append(")")
                    .append("obj")
                    .append(")")
                    .append(".")
                    .append(method)
                    .append("(");

        stringBuilder.append(")");

        stringBuilder.append("}");
        return stringBuilder.toString();
    }
}
